package controller

import (
	"blog/middleware"
	"blog/model"
	"blog/utils/errmsg"
	"net/http"
	"regexp"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
)

type UserInfo struct {
	model.User
	Password2 string `json:"password2"`
}

func Register(ctx *gin.Context) {
	// 通过结构体 接收参数
	var userinfo UserInfo
	if err := ctx.ShouldBindJSON(&userinfo); err != nil {
		ctx.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}
	username := userinfo.Username
	password := userinfo.Password
	password2 := userinfo.Password2
	phone := userinfo.Phone
	// 检验参数
	if username == "" || password == "" || password2 == "" || phone == "" {
		ctx.JSON(http.StatusOK, gin.H{
			"status":  errmsg.ERROR_ARG_NOT_ALL,
			"message": errmsg.GetErrMsg(errmsg.ERROR_ARG_NOT_ALL),
		})
		return
	}
	// 用户名
	if len(username) < 5 || len(username) > 12 {
		ctx.JSON(http.StatusOK, gin.H{
			"status":  4001,
			"message": "用户名的长度为5-12位",
		})
		return
	}
	user, _ := model.GetUser(username)
	if user.Id != 0 {
		ctx.JSON(http.StatusOK, gin.H{
			"status":  errmsg.ERROR_USERNAME_USED,
			"message": errmsg.GetErrMsg(errmsg.ERROR_USERNAME_USED),
		})
		return
	}
	// 密码
	if len(password) < 8 || len(password) > 20 {
		ctx.JSON(http.StatusOK, gin.H{
			"status":  4001,
			"message": "密码的长度为8-20位",
		})
		return
	}
	if password != password2 {
		ctx.JSON(http.StatusOK, gin.H{
			"status":  4001,
			"message": "两次输入的密码不一致",
		})
		return
	}
	// 校验手机号
	phoneRegexp := regexp.MustCompile(`^1[3-9]\d{9}$`)
	isvalidPhone := phoneRegexp.MatchString(phone)
	if !isvalidPhone {
		ctx.JSON(http.StatusOK, gin.H{
			"status":  4001,
			"message": "手机号格式不正确",
		})
		return
	}
	// 保存
	_, err := model.AddUser(username, password, phone)
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"status":  errmsg.ERROR_SAVE_FAILED,
			"message": errmsg.GetErrMsg(errmsg.ERROR_SAVE_FAILED),
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"status":  errmsg.SUCCESS,
		"message": errmsg.GetErrMsg(errmsg.SUCCESS),
	})
}

func Login(ctx *gin.Context) {
	// 接收参数
	var user model.User
	_ = ctx.ShouldBindJSON(&user)
	username := user.Username
	password := user.Password
	// 校验参数
	if len(username) < 5 || len(username) > 12 {
		ctx.JSON(http.StatusOK, gin.H{
			"status":  errmsg.ERROR,
			"message": "用户名长度为5-12位的字符",
		})
	}
	if len(password) < 8 || len(password) > 20 {
		ctx.JSON(http.StatusOK, gin.H{
			"status":  errmsg.ERROR,
			"message": "密码长度为8-20位的数字或字符",
		})
	}
	code := model.CheckLogin(username, password)
	if code == errmsg.SUCCESS {
		setToken(ctx, username)
	} else {
		ctx.JSON(http.StatusOK, gin.H{
			"status":  code,
			"data":    username,
			"message": errmsg.GetErrMsg(code),
		})
	}
}

// token生成函数
func setToken(ctx *gin.Context, username string) {
	j := middleware.NewJWT()
	claims := middleware.MyClaims{
		Username: username,
		StandardClaims: jwt.StandardClaims{
			NotBefore: time.Now().Unix() - 100,
			ExpiresAt: time.Now().Unix() + 604800,
			Issuer:    "Wch",
		},
	}
	token, err := j.CreateToken(claims)
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"status":  errmsg.ERROR,
			"message": errmsg.GetErrMsg(errmsg.ERROR),
			"token":   token,
		})
	}
	ctx.JSON(http.StatusOK, gin.H{
		"status":  200,
		"data":    username,
		"message": errmsg.GetErrMsg(200),
		"token":   token,
	})
}
